/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package suministros.ejb30.DAO;

import java.io.InputStream;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.PersistenceUnit;
import suministros.ejb30.entity.DetalleOrden;
import suministros.ejb30.entity.Orden;
import suministros.ejb30.entity.Tipo;
import suministros.ejb30.helper.EmailVacioException;
import suministros.ejb30.helper.Utiles_Convertir;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.Resource;
import javax.persistence.Query;
import javax.sql.DataSource;
import net.sf.jasperreports.engine.JasperPrint;
import org.apache.commons.io.IOUtils;
import suministros.ejb30.TO.ComprobantePagoTO;
import suministros.ejb30.TO.DetalleImpuestoTO;
import suministros.ejb30.TO.DetalleOrdenTO;
import suministros.ejb30.TO.ImpuestoTO;
import suministros.ejb30.TO.LicitacionActividadTO;
import suministros.ejb30.TO.LicitacionSuministroTO;
import suministros.ejb30.TO.OrdenTO;
import suministros.ejb30.TO.ParametrosConsultaTO;
import suministros.ejb30.TO.RegularizacionMovimientoTO;
import suministros.ejb30.TO.TabRecuTO;
import suministros.ejb30.TO.TipoTO;
import suministros.ejb30.TO.ZonaTO;
import suministros.ejb30.entity.ComprobantePago;
import suministros.ejb30.entity.DetalleImpuestoFactor;

import suministros.ejb30.entity.DetalleOrdenImpuesto;
import suministros.ejb30.entity.DetalleOrdenPK;

import suministros.ejb30.entity.DetallePedidoSuministroPK;
import suministros.ejb30.entity.DetallePlantillaImpuesto;
import suministros.ejb30.entity.GrupoSuministros;
import suministros.ejb30.entity.Impuesto;
import suministros.ejb30.entity.Movimiento;
import suministros.ejb30.entity.Suministros;

import suministros.ejb30.helper.NumberToLetterConverter;
import suministros.ejb30.helper.Utiles_MensajesEmail;

/**
 *
 * @author Luis_Angel
 */
@Stateless
public class SumiGestionOrdenesDAO implements SumiGestionOrdenesDAOLocal {

    @EJB
    private SumiGestionProveedorLocal sumiGestionProveedor;
    @EJB
    private ReporteGeneraLocal reporteGenera;
    @EJB
    private SumiGestionPedidoDAOLocal sumiGestionPedidoDAO;
    @PersistenceUnit(unitName = "suministros-pu")
    EntityManagerFactory emf;
    EntityManager em;
    @Resource(name = "jdbc/Administracion")
    DataSource dsAdministracion;

    @PostConstruct
    public void inicializaBean() {
        this.em = this.emf.createEntityManager();
    }

    @PreDestroy
    public void finalizaBean() {
        this.em.close();
    }

    public String insertarOrden(Orden orden, List<DetalleOrden> detalles) throws Exception {
        String codigo = null;
        //JasperPrint reporte_retorno;
        EntityTransaction tx = this.em.getTransaction();
        tx.begin();

        try {
            codigo = this.getIdOrden(orden);
            System.out.println("" + codigo);
            Tipo tipo_noAtendido = Utiles_Convertir.convertirToTipo_TipoTO(this.sumiGestionPedidoDAO.getTipoCampoCodigo("id_tipo_estado_orden", "NA"));

            orden.setNroOrden(codigo);
            orden.setEstadoAtencion(tipo_noAtendido);
            orden.setValorTotal(orden.getValorTotal().setScale(2,RoundingMode.HALF_UP));
            orden.setFechaOperacion(new Date());

            this.em.persist(orden);

            int plantilla = orden.getPlantillaImpuesto().getIdTablaTipo();
            BigDecimal monto_total = orden.getValorTotal();

            BigDecimal total_impuesto = new BigDecimal("0.0");
            BigDecimal monto_redondeo = orden.getMonto_utilizado();
            System.out.println("monto_rdeondeo: " + monto_redondeo);
            List<DetalleImpuestoTO> detalle_impuesto = this.retornarDetallesDeImpuesto(plantilla, monto_total);
            for (DetalleImpuestoTO dt_imp : detalle_impuesto) {
                DetalleOrdenImpuesto doi = new DetalleOrdenImpuesto(codigo, dt_imp.getId_impuesto());
                doi.setCtaDebe(dt_imp.getCta_debe());
                doi.setCtaHaber(dt_imp.getCta_haber());
                doi.setImpuesto(new Impuesto(dt_imp.getId_impuesto()));
                doi.setPorcentajeImpuesto(dt_imp.getPorcentaje());
                doi.setMonto(dt_imp.getMonto().add(monto_redondeo));
                total_impuesto = total_impuesto.add(dt_imp.getMonto().add(monto_redondeo));
                this.em.persist(doi);
            }
            total_impuesto = total_impuesto.setScale(2,RoundingMode.HALF_UP);
            orden.setValorImpuesto(total_impuesto);
            orden.setMonto_literal(NumberToLetterConverter.convertNumberToLetter(orden.getValorTotal().add(total_impuesto).setScale(2, RoundingMode.HALF_UP), orden.getTipoMoneda().getDescripcionValor()).toUpperCase());
            orden.setMonto_utilizado(BigDecimal.ZERO);
            this.em.merge(orden);

            Tipo tipo_estado_detalle_pedido = Utiles_Convertir.convertirToTipo_TipoTO(this.sumiGestionPedidoDAO.getTipoCampoCodigo("id_tipo_estado_pedido", "AL"));
            for (DetalleOrden detalle : detalles) {
                detalle.setDetalleOrdenPK(new DetalleOrdenPK(codigo, detalle.getDetalleOrdenPK().getCorrelativo()));
                Suministros sumi = this.em.find(Suministros.class, detalle.getIDSuministro());
                GrupoSuministros grupo = this.em.find(GrupoSuministros.class, sumi.getCodGrupoSumi().getCodGrupoSumi());
                String cta = "";
                String cta_aux = null;

                if (Utiles_Convertir.convertirToTipo_TipoTO(this.sumiGestionPedidoDAO.getTipoCampoCodigo("id_tipo_suministro", "B")).getIdTablaTipo().intValue() == grupo.getTipoSuministros().getIdTablaTipo().intValue()) {
                    cta = grupo.getCuenta_compra();
                } else if (Utiles_Convertir.convertirToTipo_TipoTO(this.sumiGestionPedidoDAO.getTipoCampoCodigo("id_tipo_suministro", "S")).getIdTablaTipo().intValue() == grupo.getTipoSuministros().getIdTablaTipo().intValue()) {
                    cta = grupo.getCuenta_servicio();
                } else if (Utiles_Convertir.convertirToTipo_TipoTO(this.sumiGestionPedidoDAO.getTipoCampoCodigo("id_tipo_suministro", "A")).getIdTablaTipo().intValue() == grupo.getTipoSuministros().getIdTablaTipo().intValue()) {
                    cta = grupo.getCuenta_materiales();
                }
                detalle.setCta_cble(cta);
                detalle.setCta_cble_aux(cta_aux);
                this.em.persist(detalle);

                // DetallePedidoSuministroTO dpsto =sumiGestionPedidoDAO.getDetallePedidoSuministro(detalle.getCodPedido(),detalle.getIDSuministro());
                // DetallePedidoSuministro dpsenty =  Utiles_Convertir.convertirToDetallePedidoSumi_DetallePedidoSumiTO(dpsto);
                //dpsenty.setTipoEstadoPedido(tipo_estado_detalle_pedido);
                //DetallePedidoSuministro dpsenty = em.find(DetallePedidoSuministro.class,new DetallePedidoSuministroPK(detalle.getCodPedido(),detalle.getIDSuministro()));
                //dpsenty.setTipoEstadoPedido(tipo_estado_detalle_pedido);

                //this.em.merge(dpsenty);
                   /* if(orden.getId_licitacion()!=null){
                DetalleLicitacion dln = em.find(DetalleLicitacion.class,new DetalleLicitacionPK(orden.getId_licitacion(),detalle.getIDSuministro()));

                dln.setCantidadAdquirida(dln.getCantidadAdquirida().add(detalle.getCantidad()));
                dln.setMontoAdquirido(dln.getMontoAdquirido().add(detalle.getCantidad().multiply(detalle.getPrecioUnitario())));
                this.em.merge(dln);


                Licitacion li = em.find(Licitacion.class,orden.getId_licitacion());
                li.setMontoAdquirido(li.getMontoAdquirido().add(detalle.getCantidad().multiply(detalle.getPrecioUnitario())));
                this.em.merge(li);

                }*/

            }

            /* if(orden.getIdproyecto()!=null){
            Proyecto po = em.find(Proyecto.class,orden.getIdproyecto());
            po.setMontoUtilizado(po.getMontoUtilizado().add(orden.getValorTotal()));
            this.em.merge(po);
            }*/

            this.em.flush();
            tx.commit();

        } catch (Exception e) {
            tx.rollback();
            throw e;
        }
        /* Map parameters = new HashMap();
        parameters.put("cod_orden",codigo);
        int tipo_orden =this.sumiGestionPedidoDAO.getTipoCampoCodigo("tipo_Orden", "01").getId_tabla_tipo();
        if(tipo_orden==tipo){
        reporte_retorno = reporteGenera.generarReporte("reporteOrden.jasper", parameters);
        parameters.put("asunto",Utiles_MensajesEmail.ASUNTO_NUEVA_ORDEN_COMPRA);
        parameters.put("mensaje", Utiles_MensajesEmail.NUEVA_ORDEN_COMPRA);
        }
        else{
        reporte_retorno = reporteGenera.generarReporte("reporteOrden_servicio.jasper", parameters);
        parameters.put("asunto",Utiles_MensajesEmail.ASUNTO_NUEVA_ORDEN_SERVICIO);
        parameters.put("mensaje", Utiles_MensajesEmail.NUEVA_ORDEN_SERVICIO);
        }

        // enviar a email
        String email = sumiGestionProveedor.verificaEmailProveedor(orden.getCodProveedor().getCodProveedor());
        parameters.put("email", email);
        reporteGenera.generarReporteAEmail(reporte_retorno, parameters);*/

        return codigo;
    }

    public void persist(Object object) {
        em.persist(object);
    }

    public String getIdOrden(Orden orden) throws Exception {
        String retorno = null;
        Connection cnx = null;
        try {
            //Utiles_Fecha fecha = new Utiles_Fecha(orden.getFechaemision());
            cnx = this.dsAdministracion.getConnection();
            CallableStatement csLlamada = cnx.prepareCall("{? = call [dbo].[f_sumi_getcodigoOrden](?,?,?,?)}");
            csLlamada.registerOutParameter(1, 12);
            csLlamada.setInt(2, orden.getTipoorden().getIdTablaTipo());
            csLlamada.setString(3, orden.getAno());
            csLlamada.setString(4, orden.getMes());
            csLlamada.setString(5, orden.getEmpresa().getIdEmpresa());
            csLlamada.execute();
            retorno = csLlamada.getString(1);
        } catch (SQLException ex) {
            throw ex;
        } finally {
            try {
                cnx.close();
            } catch (Exception ex) {
                Logger.getLogger(SumiGestionPedidoDAO.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        return retorno;
    }

    public OrdenTO isExisteOrden(String nro_orden) throws Exception {
        Query consulta = this.em.createNativeQuery("Select o.nro_orden,CONVERT(VarChar(50), o.Fecha_emision, 103),o.cod_proveedor,o.forma_pago,o.valor_total+o.valor_impuesto,o.monto_utilizado,p.razon_social,t.descripcion_valor "
                + "from Orden o inner join proveedor p on o.cod_proveedor=p.cod_proveedor inner join tipo t on t.id_tabla_tipo=o.tipo_moneda where "
                + "o.nro_orden ='" + nro_orden + "'");
        return (OrdenTO) Utiles_Convertir.convertirToBeanBinding_Orden1(consulta.getResultList()).get(0);
    }

    public boolean insertarComporbanteDeOrden(ComprobantePago comp_pago, String cod_orden) throws Exception {
        boolean retorno = false;
        Orden tmp_orden = null;
        if (this.buscarComprobanteDeProveedor(comp_pago.getSerieComprobante(), comp_pago.getNumeroComprobante(), comp_pago.getCodProveedor())) {
            return false;
        } else {
            EntityTransaction tx = this.em.getTransaction();
            tx.begin();
            try {
                tmp_orden = this.em.find(Orden.class, cod_orden);
                tmp_orden.setMonto_utilizado(tmp_orden.getMonto_utilizado().add(comp_pago.getMonto()));
                this.em.persist(comp_pago);
                this.em.merge(tmp_orden);

                this.em.flush();

                tx.commit();

            } catch (Exception e) {
                tx.rollback();
                throw e;
            }

            Connection cn = dsAdministracion.getConnection();
            String sql = "insert into orden_comprobante values(?,?,?)";
            PreparedStatement st = cn.prepareStatement(sql);
            st.setString(1, tmp_orden.getNroOrden());
            st.setLong(2, comp_pago.getIdComprobante());
            st.setBigDecimal(3, comp_pago.getMonto());
            st.executeUpdate();
            cn.close();
            retorno = true;



        }
        return retorno;
    }

    public boolean buscarComprobanteDeProveedor(String cod_proveedor, String serie, String numero) throws Exception {
        Query consulta = this.em.createNativeQuery("select count(0) from comprobantePago where cod_proveedor = '" + cod_proveedor + "' and serie_comprobante = '" + serie + "' and numero_comprobante = '" + numero + "'");

        if (consulta.getResultList().get(0).toString().equalsIgnoreCase("[0]")) {
            return false;
        } else {
            return true;
        }
    }

    public List<DetalleImpuestoTO> retornarDetallesDeImpuesto(int plantilla, BigDecimal monto) throws Exception {

        Query consulta = this.em.createNativeQuery("select i.id_impuesto,dif.porcentaje,i.descripcion_impuesto,i.cta_debe,i.cta_haber," + monto + "*dif.porcentaje as monto "
                + "from Detalle_Plantilla_Impuesto dpi inner join Tipo t1 on dpi.id_plantilla=t1.id_tabla_tipo "
                + "inner join impuesto i on dpi.id_impuesto=i.id_impuesto "
                + "inner join DetalleImpuestoFactor dif on dpi.id_impuesto=dif.id_impuesto "
                + "where dpi.id_plantilla=" + plantilla + " and " + monto + " between dif.monto_desde and dif.monto_hasta");

        return Utiles_Convertir.convertirToBeanBinding_DetalleImpuestoTO(consulta.getResultList());
    }

    public List<LicitacionSuministroTO> verificarDetallePedidoEnLicitacion(String cod_pedido) throws Exception {
        Integer tipo_admin = Utiles_Convertir.convertirToTipo_TipoTO(this.sumiGestionPedidoDAO.getTipoCampoCodigo("tipo_administradorTarea", "01")).getIdTablaTipo();
        Integer tipo_estado = Utiles_Convertir.convertirToTipo_TipoTO(this.sumiGestionPedidoDAO.getTipoCampoCodigo("id_tipo_estado_pedido", "AC")).getIdTablaTipo();
        Query consulta = this.em.createNativeQuery("SELECT s.ID_Suministro,s.descripcion,li.codProceso,pro.cod_proveedor,pro.razon_social,dl.cantidad,dl.cantidad-dl.cantidadAdquirida,dl.precio,dps.cantidad_pedida  FROM Detalle_Pedido_Suministro dps INNER JOIN Suministros s ON dps.ID_Suministro = s.ID_Suministro  inner join Pedido p on dps.Cod_Pedido=p.Cod_Pedido  inner join detalleLicitacion dl on dps.ID_Suministro= dl.id_suministro inner join Licitacion li on dl.codProceso=li.codProceso inner join proveedor pro on li.cod_proveedor = pro.cod_proveedor where dps.Cod_Pedido='" + cod_pedido + "' and dps.Tipo_Estado_Pedido=" + tipo_estado + " and dps.id_tipo_administrador_tarea=" + tipo_admin + " and li.alta=1");
        return Utiles_Convertir.convertirToBeanBinding_LicitacionSuministroTO(consulta.getResultList());
    }

    public List<LicitacionSuministroTO> verificarDetallePedidoEnLicitacion(DetallePedidoSuministroPK detalle_pedido) throws Exception {
        Integer tipo_admin = Utiles_Convertir.convertirToTipo_TipoTO(this.sumiGestionPedidoDAO.getTipoCampoCodigo("tipo_administradorTarea", "01")).getIdTablaTipo();
        Integer tipo_estado = Utiles_Convertir.convertirToTipo_TipoTO(this.sumiGestionPedidoDAO.getTipoCampoCodigo("id_tipo_estado_pedido", "AC")).getIdTablaTipo();
        Query consulta = this.em.createNativeQuery("SELECT s.ID_Suministro,s.descripcion,li.codProceso,pro.cod_proveedor,pro.razon_social,dl.cantidad,dl.cantidad-dl.cantidadAdquirida,dl.precio,dps.cantidad_pedida  FROM Detalle_Pedido_Suministro dps INNER JOIN Suministros s ON dps.ID_Suministro = s.ID_Suministro  inner join Pedido p on dps.Cod_Pedido=p.Cod_Pedido  inner join detalleLicitacion dl on dps.ID_Suministro= dl.id_suministro inner join Licitacion li on dl.codProceso=li.codProceso inner join proveedor pro on li.cod_proveedor = pro.cod_proveedor where dps.Cod_Pedido='" + detalle_pedido.getCodPedido() + "' and dps.id_suministro ='" + detalle_pedido.getIDSuministro() + "' and dps.Tipo_Estado_Pedido=" + tipo_estado + " and dps.id_tipo_administrador_tarea=" + tipo_admin + " and li.alta=1");
        return Utiles_Convertir.convertirToBeanBinding_LicitacionSuministroTO(consulta.getResultList());
    }

    public List<LicitacionActividadTO> getActividadesPorLicitacionEspecifica(String id_licitacion, String id_suministro) throws Exception {
        Query consulta = this.em.createNativeQuery("SELECT DetalleLicitacionActividad.codProceso, DetalleLicitacionActividad.id_suministro, DetalleLicitacionActividad.tipo_actividad, Tipo.descripcion_valor,"
                + "DetalleLicitacionActividad.codigoItem, DetalleLicitacionActividad.descripcion, DetalleLicitacionActividad.tipo_unidad, DetalleLicitacionActividad.cantidad,"
                + "DetalleLicitacionActividad.costo_unitario, DetalleLicitacionActividad.cantidad-DetalleLicitacionActividad.cantidad_adquirida,DetalleLicitacionActividad.monto_adquirido,DetalleLicitacionActividad.tipo_actividad "
                + "FROM DetalleLicitacionActividad INNER JOIN "
                + "Tipo ON DetalleLicitacionActividad.tipo_actividad = Tipo.id_tabla_tipo  where DetalleLicitacionActividad.codProceso='" + id_licitacion + "'  and DetalleLicitacionActividad.id_suministro='" + id_suministro + "'");
        return Utiles_Convertir.convertirToBeanBinding_LicitacionActividadTO(consulta.getResultList());
    }

    public List<OrdenTO> consultarOrden(ParametrosConsultaTO parametros, int tipo_orden, int pagActual, int pagTamanno) throws Exception {
        String sql = "Select o.nro_orden,z.nom_zona,CONVERT(VarChar(50), o.Fecha_emision, 103),o.cod_proveedor,o.valor_total+o.valor_impuesto,o.estado_atencion,t1.descripcion_valor,CONVERT(VarChar(50), o.Fecha_propuesta, 103),o.referencia,o.observacion,o.forma_pago,o.id_zona,o.id_almacen,o.id_ubicacion,o.tipo_moneda,o.cambio_moneda,o.plantilla_impuesto,DATEDIFF(day, o.fecha_emision, o.fecha_propuesta) AS dias "
                + "from Orden o inner join zona z on o.id_zona=z.id_zona inner join tipo t1 on o.estado_atencion = t1.id_tabla_tipo " + getCadenaWhere(parametros, tipo_orden) + " order by o.fecha_operacion desc";
        System.out.println("" + sql);
        Query consulta = this.em.createNativeQuery(sql);
        return Utiles_Convertir.convertirToBeanBinding_Orden2(consulta.setFirstResult(pagActual * pagTamanno).setMaxResults(pagTamanno).getResultList());
    }

    public List<ComprobantePagoTO> consultarComprobante(ParametrosConsultaTO parametros, int pagActual, int pagTamanno) throws Exception {
        String cadena_where = "";
        if (parametros.getRuc_proveedor() != null) {
            cadena_where += "where cp.cod_proveedor = '" + parametros.getRuc_proveedor() + "' ";
        }
        if (parametros.getId_zona() != null) {
            if (cadena_where.length() == 0) {
                cadena_where += "where o.id_zona = '" + parametros.getId_zona() + "' ";
            } else {
                cadena_where += "and o.id_zona = '" + parametros.getId_zona() + "' ";
            }
        }
        if (parametros.getAnio() != null) {
            if (cadena_where.length() == 0) {
                cadena_where += "where cp.ano = '" + parametros.getAnio() + "' ";
            } else {
                cadena_where += "and cp.ano = '" + parametros.getAnio() + "' ";
            }
        }
        if (parametros.getMes() != null) {
            if (cadena_where.length() == 0) {
                cadena_where += "where cp.mes = '" + parametros.getMes() + "' ";
            } else {
                cadena_where += "and cp.mes = '" + parametros.getMes() + "' ";
            }
        }
        if (parametros.getNro_orden() != null) {
            if (cadena_where.length() == 0) {
                cadena_where += "where o.nro_orden = '" + parametros.getNro_orden() + "' ";
            } else {
                cadena_where += "and o.nro_orden = '" + parametros.getNro_orden() + "' ";
            }
        }

        String sql = "select cp.id_comprobante,cp.serie_comprobante,cp.numero_comprobante,cp.cod_proveedor,CONVERT(VarChar(50), cp.fecha_ingreso, 103),CONVERT(VarChar(50), cp.fecha_pago, 103),t1.descripcion_valor,o.nro_orden,z.nom_zona,cp.monto "
                + "from orden o inner join orden_comprobante oc on o.nro_orden= oc.nro_orden inner  join  comprobantepago cp on oc.id_comprobante=cp.id_comprobante "
                + "inner join Tipo t1 on cp.cod_tipo_comprobante = t1.id_tabla_tipo inner join zona z on o.id_zona = z.id_zona " + cadena_where + " order by cp.fecha_ingreso desc";
        System.out.println("" + sql);
        Query consulta = this.em.createNativeQuery(sql);
        return Utiles_Convertir.convertirTOComprobantePagoTO(consulta.setFirstResult(pagActual * pagTamanno).setMaxResults(pagTamanno).getResultList());
    }

    public List<ComprobantePagoTO> getComprobantesOrden(String nro_orden) throws Exception {

        String sql = "select cp.id_comprobante,cp.serie_comprobante,cp.numero_comprobante,cp.cod_proveedor,CONVERT(VarChar(50), cp.fecha_ingreso, 103),CONVERT(VarChar(50), cp.fecha_pago, 103),t1.descripcion_valor,o.nro_orden,z.nom_zona,cp.monto "
                + "from orden o inner join orden_comprobante oc on o.nro_orden= oc.nro_orden inner  join  comprobantepago cp on oc.id_comprobante=cp.id_comprobante "
                + "inner join Tipo t1 on cp.cod_tipo_comprobante = t1.id_tabla_tipo inner join zona z on o.id_zona = z.id_zona where o.nro_orden='" + nro_orden + "' order by cp.fecha_ingreso desc";
        System.out.println("" + sql);
        Query consulta = this.em.createNativeQuery(sql);
        return Utiles_Convertir.convertirTOComprobantePagoTO(consulta.getResultList());
    }

    public boolean anularOrden(String nro_orden) throws Exception {
        boolean retorno = false;

        EntityTransaction tx = this.em.getTransaction();
        tx.begin();
        try {

            Tipo tipo_estado_anulado = Utiles_Convertir.convertirToTipo_TipoTO(this.sumiGestionPedidoDAO.getTipoCampoCodigo("id_tipo_estado_orden", "AN"));
            Orden tmp_orden = this.em.find(Orden.class, nro_orden);
            tmp_orden.setEstadoAtencion(tipo_estado_anulado);
            this.em.merge(tmp_orden);
            this.em.flush();
            tx.commit();
            retorno = true;
        } catch (Exception e) {
            tx.rollback();
            throw e;
        }

        return retorno;
    }

    public boolean finalizarOrden(String nro_orden) throws Exception {
        boolean retorno = false;

        EntityTransaction tx = this.em.getTransaction();
        tx.begin();
        try {

            Tipo tipo_estado_anulado = Utiles_Convertir.convertirToTipo_TipoTO(this.sumiGestionPedidoDAO.getTipoCampoCodigo("id_tipo_estado_orden", "TA"));
            Orden tmp_orden = this.em.find(Orden.class, nro_orden);
            tmp_orden.setEstadoAtencion(tipo_estado_anulado);
            this.em.merge(tmp_orden);
            this.em.flush();
            tx.commit();
            retorno = true;
        } catch (Exception e) {
            tx.rollback();
            throw e;
        }

        return retorno;
    }

    public List<DetalleOrdenTO> getListaDetalleOrden(String nro_orden) throws Exception {
        Query consulta = this.em.createNativeQuery("select do.ID_Suministro,s.descripcion,do.cantidad as cantidad,t1.descripcion_valor as unidades,do.precio_unitario as precio_unitario,(do.cantidad*do.precio_unitario) as subtotal "
                + "from DetalleOrden do inner join Suministros s on s.ID_Suministro=do.ID_Suministro inner join Tipo t1 on s.tipo_unidad_medida=t1.id_tabla_tipo "
                + "where do.nro_orden='" + nro_orden + "'");
        return Utiles_Convertir.convertirToBeanBinding_DetalleOrdenTO(consulta.getResultList());
    }

    public boolean modificarOrden(Orden orden, List<DetalleOrden> detalles) throws Exception {
        boolean retorno = false;
        EntityTransaction tx = this.em.getTransaction();
        tx.begin();

        try {
            Orden tmp_orden = this.em.find(Orden.class, orden.getNroOrden());
            tmp_orden.setCambioMoneda(orden.getCambioMoneda());
            tmp_orden.setCodProveedor(orden.getCodProveedor());
            tmp_orden.setComprobantePago(orden.getComprobantePago());
            tmp_orden.setFechapropuesta(orden.getFechapropuesta());
            tmp_orden.setFormaPago(orden.getFormaPago());
            tmp_orden.setIdAlmacen(orden.getIdAlmacen());
            tmp_orden.setIdUbicacion(orden.getIdUbicacion());
            tmp_orden.setIdZona(orden.getIdZona());
            tmp_orden.setPlantillaImpuesto(orden.getPlantillaImpuesto());
            tmp_orden.setObservacion(orden.getObservacion());
            tmp_orden.setReferencia(orden.getReferencia());

            int plantilla = orden.getPlantillaImpuesto().getIdTablaTipo();
            BigDecimal monto_total = orden.getValorTotal();

            Query q = this.em.createNamedQuery("DetalleOrdenImpuesto.findByNroOrden");
            q.setParameter("nroOrden", orden.getNroOrden());
            List<DetalleOrdenImpuesto> impuestos_orden = q.getResultList();
            for (DetalleOrdenImpuesto dus : impuestos_orden) {
                this.em.remove(dus);
                this.em.flush();
            }


            BigDecimal total_impuesto = new BigDecimal("0.0");
            List<DetalleImpuestoTO> detalle_impuesto = this.retornarDetallesDeImpuesto(plantilla, monto_total);
            for (DetalleImpuestoTO dt_imp : detalle_impuesto) {
                DetalleOrdenImpuesto doi = new DetalleOrdenImpuesto(orden.getNroOrden(), dt_imp.getId_impuesto());
                doi.setCtaDebe(dt_imp.getCta_debe());
                doi.setCtaHaber(dt_imp.getCta_haber());
                doi.setImpuesto(new Impuesto(dt_imp.getId_impuesto()));
                doi.setPorcentajeImpuesto(dt_imp.getPorcentaje());
                doi.setMonto(dt_imp.getMonto());
                total_impuesto = total_impuesto.add(dt_imp.getMonto());
                this.em.persist(doi);
            }

            tmp_orden.setValorImpuesto(total_impuesto);
            tmp_orden.setMonto_literal(NumberToLetterConverter.convertNumberToLetter(orden.getValorTotal().add(total_impuesto).setScale(2, RoundingMode.HALF_UP), orden.getTipoMoneda().getDescripcionValor()).toUpperCase());
            this.em.merge(tmp_orden);

            q = this.em.createNamedQuery("DetalleOrden.findByNroOrden");
            q.setParameter("nroOrden", orden.getNroOrden());
            List<DetalleOrden> detalles_orden = q.getResultList();
            for (DetalleOrden dus : detalles_orden) {
                this.em.remove(dus);
                this.em.flush();
            }

            // Tipo tipo_estado_detalle_pedido = Utiles_Convertir.convertirToTipo_TipoTO(this.sumiGestionPedidoDAO.getTipoCampoCodigo("id_tipo_estado_pedido", "AL"));
            for (DetalleOrden detalle : detalles) {
                detalle.setDetalleOrdenPK(new DetalleOrdenPK(orden.getNroOrden(), detalle.getDetalleOrdenPK().getCorrelativo()));
                this.em.persist(detalle);

                // DetallePedidoSuministroTO dpsto =sumiGestionPedidoDAO.getDetallePedidoSuministro(detalle.getCodPedido(),detalle.getIDSuministro());
                // DetallePedidoSuministro dpsenty =  Utiles_Convertir.convertirToDetallePedidoSumi_DetallePedidoSumiTO(dpsto);
                //dpsenty.setTipoEstadoPedido(tipo_estado_detalle_pedido);
                   /* DetallePedidoSuministro dpsenty = em.find(DetallePedidoSuministro.class,new DetallePedidoSuministroPK(detalle.getCodPedido(),detalle.getIDSuministro()));
                dpsenty.setTipoEstadoPedido(tipo_estado_detalle_pedido);
                System.out.println(detalle.getCodPedido()+"-"+detalle.getIDSuministro()+"-"+dpsenty.getTipoEstadoPedido().getIdTablaTipo());
                this.em.merge(dpsenty);*/

            }

            this.em.flush();
            tx.commit();
            retorno = true;
        } catch (Exception e) {
            tx.rollback();
            throw e;
        }

        return retorno;
    }

    public byte[] getComprobanteArchivo(int id_comprobante) throws Exception {
        byte[] data = null;
        Connection cnx = null;
        try {
            //Utiles_Fecha fecha = new Utiles_Fecha(orden.getFechaemision());
            cnx = this.dsAdministracion.getConnection();
            PreparedStatement csLlamada = cnx.prepareStatement("select archivo from comprobantepago where id_comprobante=" + id_comprobante);
            ResultSet rs = csLlamada.executeQuery();
            rs.next();

            InputStream is = rs.getBinaryStream(1);
            if (is != null) {
                data = IOUtils.toByteArray(is);
            }
            /* Filefile = new File(id_comprobante+".pdf");
            org.apache.commons.io.FileUtils.writeByteArrayToFile(file, data);*/

        } catch (SQLException ex) {
            throw ex;
        } finally {
            try {
                cnx.close();
            } catch (Exception ex) {
                Logger.getLogger(SumiGestionPedidoDAO.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        return data;

    }

    public boolean modificarComprobanteArchivo(int id_comprobante, byte[] archivo) throws Exception {
        boolean retorno = false;
        EntityTransaction tx = this.em.getTransaction();
        tx.begin();
        try {

            ComprobantePago cp = this.em.find(ComprobantePago.class, new Long(id_comprobante));
            cp.setArchivo(archivo);
            this.em.merge(cp);
            this.em.flush();
            tx.commit();
            retorno = true;
        } catch (Exception e) {
            tx.rollback();
            throw e;
        }


        return retorno;
    }

    public boolean generaDocumentoAEmail(String nro_orden, int tipo, String cod_proveedor) throws EmailVacioException, Exception {
        boolean retorno = false;
        JasperPrint documento = null;
        Map parameters = new HashMap();
        parameters.put("cod_orden", nro_orden);
        int tipo_orden = this.sumiGestionPedidoDAO.getTipoCampoCodigo("tipo_Orden", "01").getId_tabla_tipo();
        if (tipo_orden == tipo) {
            documento = reporteGenera.generarReporte("reporteOrden.jasper", parameters);
            parameters.put("asunto", Utiles_MensajesEmail.ASUNTO_NUEVA_ORDEN_COMPRA);
            parameters.put("mensaje", Utiles_MensajesEmail.NUEVA_ORDEN_COMPRA);
        } else {
            documento = reporteGenera.generarReporte("reporteOrden_servicio.jasper", parameters);
            parameters.put("asunto", Utiles_MensajesEmail.ASUNTO_NUEVA_ORDEN_SERVICIO);
            parameters.put("mensaje", Utiles_MensajesEmail.NUEVA_ORDEN_SERVICIO);
        }

        // enviar a email
        String email = null;
        email = sumiGestionProveedor.verificaEmailProveedor(cod_proveedor);
        //TODO imprimir email

        parameters.put("email", email);
        reporteGenera.generarReporteAEmail(documento, parameters);

        return retorno;
    }

    public int getNumeroDeOrdenes(ParametrosConsultaTO parametros, int tipo_orden) throws Exception {
        Query consulta = this.em.createNativeQuery("Select o.nro_orden,z.nom_zona,CONVERT(VarChar(50), o.Fecha_emision, 103),o.cod_proveedor,o.valor_total,o.fecha_emision,o.estado_atencion,t1.descripcion_valor,CONVERT(VarChar(50), o.Fecha_propuesta, 103),o.referencia,o.observacion,o.forma_pago,o.id_zona,o.id_almacen,o.id_ubicacion,o.tipo_moneda,o.cambio_moneda,o.plantilla_impuesto,DATEDIFF(day, o.fecha_emision, o.fecha_propuesta) AS dias "
                + "from Orden o inner join zona z on o.id_zona=z.id_zona inner join tipo t1 on o.estado_atencion = t1.id_tabla_tipo " + getCadenaWhere(parametros, tipo_orden) + " order by o.fecha_emision desc");
        return consulta.getResultList().size();
    }

    public int getNumeroDeComprobantes(ParametrosConsultaTO parametros) throws Exception {
        String cadena_where = "";
        if (parametros.getRuc_proveedor() != null) {
            cadena_where += "where cp.cod_proveedor = '" + parametros.getRuc_proveedor() + "' ";
        }
        if (parametros.getId_zona() != null) {
            if (cadena_where.length() == 0) {
                cadena_where += "where o.id_zona = '" + parametros.getId_zona() + "' ";
            } else {
                cadena_where += "and o.id_zona = '" + parametros.getId_zona() + "' ";
            }
        }
        if (parametros.getAnio() != null) {
            if (cadena_where.length() == 0) {
                cadena_where += "where cp.ano = '" + parametros.getAnio() + "' ";
            } else {
                cadena_where += "and cp.ano = '" + parametros.getAnio() + "' ";
            }
        }
        if (parametros.getMes() != null) {
            if (cadena_where.length() == 0) {
                cadena_where += "where cp.mes = '" + parametros.getMes() + "' ";
            } else {
                cadena_where += "and cp.mes = '" + parametros.getMes() + "' ";
            }
        }
        if (parametros.getNro_orden() != null) {
            if (cadena_where.length() == 0) {
                cadena_where += "where o.nro_orden = '" + parametros.getNro_orden() + "' ";
            } else {
                cadena_where += "and o.nro_orden = '" + parametros.getNro_orden() + "' ";
            }
        }


        String sql = "select cp.id_comprobante,cp.serie_comprobante,cp.numero_comprobante,cp.cod_proveedor,CONVERT(VarChar(50), cp.fecha_ingreso, 103),CONVERT(VarChar(50), cp.fecha_pago, 103),t1.descripcion_valor,o.nro_orden,z.nom_zona "
                + "from orden o inner join orden_comprobante oc on o.nro_orden= oc.nro_orden inner  join  comprobantepago cp on oc.id_comprobante=cp.id_comprobante "
                + "inner join Tipo t1 on cp.cod_tipo_comprobante = t1.id_tabla_tipo inner join zona z on o.id_zona = z.id_zona " + cadena_where + " order by cp.fecha_ingreso desc";

        Query consulta = this.em.createNativeQuery(sql);
        return consulta.getResultList().size();
    }

    private String getCadenaWhere(ParametrosConsultaTO parametros, int tipo_orden) {
        String cadena_where = "";
        if (parametros.getRuc_proveedor() != null) {
            cadena_where += "where o.cod_proveedor = '" + parametros.getRuc_proveedor() + "' ";
        }
        if (parametros.getId_zona() != null) {
            if (cadena_where.length() == 0) {
                cadena_where += "where o.id_zona = '" + parametros.getId_zona() + "' ";
            } else {
                cadena_where += "and o.id_zona = '" + parametros.getId_zona() + "' ";
            }
        }
        if (parametros.getAnio() != null) {
            if (cadena_where.length() == 0) {
                cadena_where += "where o.ano = '" + parametros.getAnio() + "' ";
            } else {
                cadena_where += "and o.ano = '" + parametros.getAnio() + "' ";
            }
        }
        if (parametros.getMes() != null) {
            if (cadena_where.length() == 0) {
                cadena_where += "where o.mes = '" + parametros.getMes() + "' ";
            } else {
                cadena_where += "and o.mes = '" + parametros.getMes() + "' ";
            }
        }

        if (parametros.getId_empresa() != null) {
            if (cadena_where.length() == 0) {
                cadena_where += "where o.id_empresa = '" + parametros.getId_empresa() + "' ";
            } else {
                cadena_where += "and o.id_empresa = '" + parametros.getId_empresa() + "' ";
            }
        }
        if (parametros.getNro_orden() != null) {
            if (cadena_where.length() == 0) {
                cadena_where += "where o.nro_orden = '" + parametros.getNro_orden() + "' ";
            } else {
                cadena_where += "and o.nro_orden = '" + parametros.getNro_orden() + "' ";
            }
        }
        if (cadena_where.length() == 0) {
            cadena_where += "where o.tipo_orden = " + tipo_orden;
        } else {
            cadena_where += "and o.tipo_orden = " + tipo_orden;
        }

        return cadena_where;
    }
    // Add business logic below. (Right-click in editor and choose
    // "Insert Code > Add Business Method")

    public List<OrdenTO> getOrdenesSinComprobante(List<ZonaTO> zonas_usuario, String id_empresa) throws Exception {
        String zonas = "";
        for (ZonaTO z : zonas_usuario) {
            if (zonas.length() == 0) {
                zonas += "'" + z.getId_zona() + "'";
            } else {
                zonas += ",'" + z.getId_zona() + "'";
            }
        }
        Integer tipo_estado =  Utiles_Convertir.convertirToTipo_TipoTO(this.sumiGestionPedidoDAO.getTipoCampoCodigo("id_tipo_estado_orden", "AN")).getIdTablaTipo();
        Query consulta = this.em.createNativeQuery("Select o.nro_orden, convert(char(10),o.fecha_emision,103),z.nom_zona,p.razon_social,o.cod_proveedor,o.forma_pago,o.valor_total+o.valor_impuesto,o.monto_utilizado,t.descripcion_valor "
                + "from Orden o  inner join zona z on o.id_zona=z.id_zona inner join proveedor p on o.cod_proveedor=p.cod_proveedor and o.id_zona in(" + zonas + ") and o.id_empresa='" + id_empresa + "' inner join tipo t on o.tipo_moneda=t.id_tabla_tipo where o.valor_total+o.valor_impuesto >o.monto_utilizado and o.estado_atencion <> "+tipo_estado.intValue()+" order by o.nro_orden ");
        return Utiles_Convertir.convertirToBeanBinding_SimpleOrdenTO(consulta.getResultList());
    }

    public String verificaDetalleOrdenEnPresupuesto(List<DetalleOrdenTO> detalle_orden, int mes) throws Exception {
        String mensaje = "";
        String tabla_mes = "";

        if (mes == Calendar.JANUARY) {
            tabla_mes = "pro_ene,uti_ene ";
        } else if (mes == Calendar.FEBRUARY) {
            tabla_mes = "pro_feb,uti_feb";
        } else if (mes == Calendar.MARCH) {
            tabla_mes = "pro_mar,uti_mar";
        } else if (mes == Calendar.APRIL) {
            tabla_mes = "pro_abr,uti_abr";
        } else if (mes == Calendar.MAY) {
            tabla_mes = "pro_may,uti_may";
        } else if (mes == Calendar.JUNE) {
            tabla_mes = "pro_jun,uti_jun";
        } else if (mes == Calendar.JULY) {
            tabla_mes = "pro_jul,uti_jul";
        } else if (mes == Calendar.AUGUST) {
            tabla_mes = "pro_ago,uti_ago";
        } else if (mes == Calendar.SEPTEMBER) {
            tabla_mes = "pro_set,uti_set";
        } else if (mes == Calendar.OCTOBER) {
            tabla_mes = "pro_oct,uti_oct";
        } else if (mes == Calendar.NOVEMBER) {
            tabla_mes = "pro_nov,uti_nov";
        } else if (mes == Calendar.DECEMBER) {
            tabla_mes = "pro_dic,uti_dic";
        }
        System.out.println("" + tabla_mes);
        Connection cn = null;

        cn = dsAdministracion.getConnection();
        List<TabRecuTO> trs = new ArrayList(1);
        for (DetalleOrdenTO dto : detalle_orden) {
            boolean b = false;
            String plantilla = "select " + tabla_mes + " from aux_tab_recu where cod_pre=? and cod_ccp1=?";

            PreparedStatement st = cn.prepareStatement(plantilla);

            st.setString(1, dto.getCodPresupuesta());
            //st.setString(2, dto.getCta_ctble1());
            ResultSet rs = st.executeQuery();
            boolean is_datos = rs.next();
            if (is_datos) {
                BigDecimal monto_mes = rs.getBigDecimal(1);
                BigDecimal utilizado_mes = rs.getBigDecimal(2);
                if (!trs.isEmpty()) {
                    for (TabRecuTO tabRecuTO : trs) {
                        /*if(tabRecuTO.getCod_presupuestal().equalsIgnoreCase(dto.getCodPresupuesta()) && tabRecuTO.getCuenta().equalsIgnoreCase(dto.getCta_ctble1())){
                        b=true;
                        utilizado_mes = utilizado_mes.add(tabRecuTO.getMonto_separado());
                        if((monto_mes.subtract(utilizado_mes)).compareTo(dto.getValor())>=0){
                        tabRecuTO.setMonto_separado(tabRecuTO.getMonto_separado().add(dto.getValor()));
                        }
                        }*/
                    }
                    /*if(!b)
                    trs.add(new TabRecuTO( dto.getCodPresupuesta(), dto.getCta_ctble1(), dto.getValor()));*/
                }
                /* else{
                trs.add(new TabRecuTO( dto.getCodPresupuesta(), dto.getCta_ctble1(), dto.getValor()));
                }*/
                if ((monto_mes.subtract(utilizado_mes)).compareTo(dto.getValor()) < 0) {
                    mensaje += "No existe suficiente presupuesto en este mes para el suministro : " + dto.getDescripcion();
                }
                System.out.println("" + monto_mes.doubleValue() + ">>" + utilizado_mes);
            }


        }
        cn.close();
        return mensaje;
    }

    public List<DetalleOrdenTO> listarOrdenesSuministros(ParametrosConsultaTO parametros) throws Exception {

        String sql = "select do.nro_orden,do.id_suministro,su.descripcion,do.cantidad,do.precio_unitario,do.cod_pedido,zo.nom_zona,convert(VarChar(20),o.fecha_emision,103) "
                + "from detalleorden do inner join orden o on do.nro_orden=o.nro_orden inner join zona zo on o.id_zona=zo.id_zona inner join suministros su on do.id_suministro=su.id_suministro "
                + " " + getCadenaWhere(parametros) + " "
                + "order by id_suministro,o.fecha_operacion asc";
        Query consulta = this.em.createNativeQuery(sql);
        System.out.println(sql);
        return Utiles_Convertir.convertirToBeanBinding_OrdenSuministros(consulta.getResultList());
    }

    public List<OrdenTO> listarOrdenesProveedores(ParametrosConsultaTO parametros) throws Exception {

        String sql = "select nro_orden,convert(VarChar(20),o.fecha_emision,103),p.cod_proveedor,p.razon_social ,o.valor_total,o.valor_impuesto,o.valor_total+o.valor_impuesto,t1.descripcion_valor,zo.nom_zona,t5.descripcion_valor,o.cambio_moneda   "
                + "from orden o inner join proveedor p on o.cod_proveedor=p.cod_proveedor "
                + "inner join zona zo on o.id_zona=zo.id_zona "
                + "inner join tipo t5 on o.estado_atencion = t5.id_tabla_tipo "
                + "inner join tipo t1 on o.plantilla_impuesto=t1.id_tabla_tipo " + getCadenaWhere(parametros) + " "
                + "order by p.razon_social asc";
        Query consulta = this.em.createNativeQuery(sql);
        System.out.println(sql);
        return Utiles_Convertir.convertirToBeanBinding_OrdenProveedores(consulta.getResultList());
    }

    public List<OrdenTO> listarOrdenesTotales(ParametrosConsultaTO parametros) throws Exception {

        String sql = "select nro_orden,convert(VarChar(20),o.fecha_emision,103),p.cod_proveedor,p.razon_social ,o.valor_total,o.valor_impuesto,o.valor_total+o.valor_impuesto,t1.descripcion_valor,zo.nom_zona, t2.descripcion_valor,t3.descripcion_valor,'',isnull(o.nro_solicitud_cotizacion,''),isnull(licitacion.descripcionProceso,''),isnull(proyecto.nom_proyecto,''),t5.descripcion_valor,o.cambio_moneda  "
                + "from orden o inner join proveedor p on o.cod_proveedor=p.cod_proveedor "
                + "inner join zona zo on o.id_zona=zo.id_zona "
                + "inner join tipo t1 on o.plantilla_impuesto=t1.id_tabla_tipo "
                + "inner join tipo t2 on o.forma_pago=t2.id_tabla_tipo "
                + "inner join tipo t3 on o.tipo_moneda=t3.id_tabla_tipo "
                + "inner join tipo t5 on o.estado_atencion = t5.id_tabla_tipo "
                + "left join proyecto on o.id_proyecto=proyecto.id_proyecto "
                + "left join licitacion on o.codProceso=licitacion.codProceso " + getCadenaWhere(parametros) + " "
                + "order by o.nro_orden asc";
        Query consulta = this.em.createNativeQuery(sql);
        System.out.println(sql);
        return Utiles_Convertir.convertirToBeanBinding_OrdenTotales(consulta.getResultList());
    }

    public List<DetalleOrdenTO> listarOrdenesCuentas(ParametrosConsultaTO parametros) throws Exception {

        String sql = "select do.nro_orden,do.id_suministro,su.descripcion,do.cantidad,do.precio_unitario,do.cod_pedido,zo.nom_zona,convert(VarChar(20),o.fecha_emision,103),isnull(do.cta_cble,''),isnull(do.cta_cble_aux,'') "
                + "from orden o inner join zona zo on o.id_zona=zo.id_zona "
                + "inner join detalleorden do on o.nro_orden=do.nro_orden "
                + "inner join suministros su on do.id_suministro=su.id_suministro "
                + getCadenaWhere(parametros);
        System.out.println(sql);
        Query consulta = this.em.createNativeQuery(sql);
        return Utiles_Convertir.convertirToBeanBinding_OrdenCuentas(consulta.getResultList());
    }

    private String getCadenaWhere(ParametrosConsultaTO parametros) {
        String cadena_where = "";
        if (parametros.getRuc_proveedor() != null) {
            cadena_where += "where o.cod_proveedor = '" + parametros.getRuc_proveedor() + "' ";
        }

        if (parametros.getId_zona() != null) {
            if (cadena_where.length() == 0) {
                cadena_where += "where o.id_zona = '" + parametros.getId_zona() + "' ";
            } else {
                cadena_where += "and o.id_zona = '" + parametros.getId_zona() + "' ";
            }
        }
        if (parametros.getAnio() != null) {
            if (cadena_where.length() == 0) {
                cadena_where += "where o.ano = '" + parametros.getAnio() + "' ";
            } else {
                cadena_where += "and o.ano = '" + parametros.getAnio() + "' ";
            }
        }
        if (parametros.getMes() != null) {
            if (cadena_where.length() == 0) {
                cadena_where += "where o.mes = '" + parametros.getMes() + "' ";
            } else {
                cadena_where += "and o.mes = '" + parametros.getMes() + "' ";
            }
        }
        if (parametros.getNro_licitacion() != null) {
            if (cadena_where.length() == 0) {
                cadena_where += "where o.codProceso = '" + parametros.getNro_licitacion() + "' ";
            } else {
                cadena_where += "and o.codProceso = '" + parametros.getNro_licitacion() + "' ";
            }

        }
        if (parametros.getId_empresa() != null) {
            if (cadena_where.length() == 0) {
                cadena_where += "where o.id_empresa = '" + parametros.getId_empresa() + "' ";
            } else {
                cadena_where += "and o.id_empresa = '" + parametros.getId_empresa() + "' ";
            }
        }
        if (parametros.getTipo_orden() != 0) {
            if (cadena_where.length() == 0) {
                cadena_where += "where o.tipo_orden = " + parametros.getTipo_orden();
            } else {
                cadena_where += "and o.tipo_orden = " + parametros.getTipo_orden();
            }
        }
        if (parametros.getFecha_inicio() != null) {
            if (cadena_where.length() == 0) {
                cadena_where += "where CONVERT(VARCHAR,o.fecha_emision,103)  >= '" + parametros.getFecha_inicio() + "' ";
            } else {
                cadena_where += "and  CONVERT(VARCHAR,o.fecha_emision,103)  >= '" + parametros.getFecha_inicio() + "' ";
            }
        }
        if (parametros.getFecha_fin() != null) {
            if (cadena_where.length() == 0) {
                cadena_where += "where CONVERT(VARCHAR,o.fecha_emision,103)  <= '" + parametros.getFecha_fin() + "' ";
            } else {
                cadena_where += "and CONVERT(VARCHAR,o.fecha_emision,103)  <= '" + parametros.getFecha_fin() + "' ";
            }
        }
        if (parametros.getId_suministro() != null) {
            if (cadena_where.length() == 0) {
                cadena_where += "where do.id_suministro = '" + parametros.getId_suministro() + "' ";
            } else {
                cadena_where += "and do.id_suministro = '" + parametros.getId_suministro() + "' ";
            }
        }


        return cadena_where;
    }

    public List<RegularizacionMovimientoTO> getMovimientosRegularizar(String ruc_proveedor) throws Exception {
        TipoTO tipo_movimiento = this.sumiGestionPedidoDAO.getTipoCampoCodigo("tipo_Movimiento", "I");
        TipoTO tipo_ingreso = this.sumiGestionPedidoDAO.getTipoCampoCodigo("tipo_Ingreso", "02");
        String sql = "select distinct mv.id_movimiento,rtrim(mv.serie)+'-'+rtrim(mv.numero), dmv.cantidad,dmv.valor,s.id_suministro,s.descripcion,t.descripcion_valor "
                + "from movimiento mv inner join detallemovimiento dmv on mv.id_movimiento=dmv.id_movimiento inner join suministros s on dmv.id_suministro=s.id_suministro inner join tipo t on s.tipo_unidad_medida=t.id_tabla_tipo "
                + "where mv.tipo_movimiento=" + tipo_movimiento.getId_tabla_tipo() + " and mv.tipo_ingreso=" + tipo_ingreso.getId_tabla_tipo() + " and mv.ruc='" + ruc_proveedor + "'";
        Query consulta = this.em.createNativeQuery(sql);
        System.out.println(sql);
        return Utiles_Convertir.convertirToBeanBinding_RegularizarMovimiento(consulta.getResultList());
    }

    public boolean regularizaMovimientos(List<RegularizacionMovimientoTO> lista, String nro_orden) throws Exception {
        boolean retorno = false;
        EntityTransaction tx = this.em.getTransaction();
        tx.begin();
        try {
            Tipo tipo_atendida = Utiles_Convertir.convertirToTipo_TipoTO(this.sumiGestionPedidoDAO.getTipoCampoCodigo("id_tipo_estado_orden", "TA"));
            Orden orden = this.em.find(Orden.class, nro_orden);
            orden.setEstadoAtencion(tipo_atendida);
            this.em.merge(orden);
            Tipo tipo_ingreso = Utiles_Convertir.convertirToTipo_TipoTO(this.sumiGestionPedidoDAO.getTipoCampoCodigo("tipo_Ingreso", "01"));
            for (RegularizacionMovimientoTO regularizacionMovimientoTO : lista) {
                Movimiento mv = this.em.find(Movimiento.class, regularizacionMovimientoTO.getId_movimiento());
                mv.setTipoIngreso(tipo_ingreso);
                mv.setNroOrden(this.em.find(Orden.class, nro_orden));
                this.em.merge(mv);
            }
            this.em.flush();
            retorno = true;
            tx.commit();
        } catch (Exception e) {
            tx.rollback();
            throw e;
        }
        return retorno;
    }

    public BigDecimal getMontoImpuesto(Integer tipo_plantilla, BigDecimal sub_total) throws Exception {
        BigDecimal retorno = BigDecimal.ZERO;
        Connection cnx = null;
        try {
            //Utiles_Fecha fecha = new Utiles_Fecha(orden.getFechaemision());
            cnx = this.dsAdministracion.getConnection();
            CallableStatement csLlamada = cnx.prepareCall("{? = call [dbo].[f_sumi_getImpuestosPreOrden](?,?)}");
            csLlamada.registerOutParameter(1, java.sql.Types.FLOAT);
            csLlamada.setInt(2, tipo_plantilla);
            csLlamada.setBigDecimal(3, sub_total);
            csLlamada.execute();
            retorno = csLlamada.getBigDecimal(1);
        } catch (SQLException ex) {
            throw ex;
        } finally {
            try {
                cnx.close();
            } catch (Exception ex) {
                Logger.getLogger(SumiGestionPedidoDAO.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        return retorno;
    }

    public List<ImpuestoTO> getListaImpuestos() throws Exception {
        Query consulta = this.em.createNativeQuery("SELECT Impuesto.id_impuesto, Impuesto.descripcion_impuesto, Impuesto.descripcion_larga_impuesto, Impuesto.cta_debe, Impuesto.cta_haber, Impuesto.efecto, "
                + " DetalleImpuestoFactor.monto_desde, DetalleImpuestoFactor.monto_hasta, DetalleImpuestoFactor.porcentaje, Detalle_Plantilla_Impuesto.id_plantilla "
                + " FROM Impuesto INNER JOIN "
                + " DetalleImpuestoFactor ON Impuesto.id_impuesto = DetalleImpuestoFactor.id_impuesto INNER JOIN "
                + " Detalle_Plantilla_Impuesto ON Impuesto.id_impuesto = Detalle_Plantilla_Impuesto.id_impuesto");
        return Utiles_Convertir.convertirToBeanBinding_ImpuestoTO(consulta.getResultList());
    }

    public boolean eliminaImpuesto(int id_impuesto) throws Exception {
        boolean retorno = false;
        EntityTransaction tx = this.em.getTransaction();
        tx.begin();
        try {

            Query q = this.em.createNamedQuery("DetalleImpuestoFactor.findByIdImpuesto");
            q.setParameter("idImpuesto", id_impuesto);
            List<DetalleImpuestoFactor> ldif = q.getResultList();
            for (DetalleImpuestoFactor detalleImpuestoFactor : ldif) {
                this.em.remove(detalleImpuestoFactor);
            }
            this.em.flush();

             q = this.em.createNamedQuery("DetallePlantillaImpuesto.findByIdImpuesto");
            q.setParameter("idImpuesto", id_impuesto);
            List<DetallePlantillaImpuesto> ldpi = q.getResultList();
            for (DetallePlantillaImpuesto d : ldpi) {
                this.em.remove(d);
            }
            this.em.flush();


            this.em.remove(this.em.find(Impuesto.class, id_impuesto));
            this.em.flush();
            tx.commit();
            retorno = true;
        } catch (Exception e) {
            e.printStackTrace();
            tx.rollback();
            throw e;
        }
        return retorno;
    }

    public boolean operaImpuesto(Impuesto impuesto, DetallePlantillaImpuesto dpi) throws Exception {
        boolean retorno = false;
        EntityTransaction tx = this.em.getTransaction();
        tx.begin();
        try {

            /* List<DetalleImpuestoFactor> detalle = new ArrayList<DetalleImpuestoFactor>();
            detalle.add(detalle_impuesto);
            impuesto.setDetalleImpuestoFactorList(detalle);*/
            /*detalle_impuesto.getDetalleImpuestoFactorPK().setIdImpuesto(impuesto.getIdImpuesto());
            this.em.merge(detalle_impuesto);*/
            Query q = this.em.createNamedQuery("DetalleImpuestoFactor.findByIdImpuesto");
            q.setParameter("idImpuesto", impuesto.getIdImpuesto());
            List<DetalleImpuestoFactor> ldif = q.getResultList();
            for (DetalleImpuestoFactor detalleImpuestoFactor : ldif) {
                this.em.remove(detalleImpuestoFactor);
                this.em.flush();
            }
            
            DetalleImpuestoFactor dif = impuesto.getDetalleImpuestoFactorList().get(0);
            impuesto.setDetalleImpuestoFactorList(null);
            if(impuesto.getIdImpuesto() == null || impuesto.getIdImpuesto()==0)
                this.em.persist(impuesto);
            else
                this.em.merge(impuesto);
            //this.em.flush();
            dif.getDetalleImpuestoFactorPK().setIdImpuesto(impuesto.getIdImpuesto());
            this.em.persist(dif);
            this.em.flush();

            dpi.getDetallePlantillaImpuestoPK().setIdImpuesto(impuesto.getIdImpuesto());
            this.em.merge(dpi);
            this.em.flush();
            tx.commit();
            retorno = true;
        } catch (Exception e) {
            e.printStackTrace();
            tx.rollback();
            throw e;
        }

        return retorno;
    }


    public boolean modificaComprobante(ComprobantePagoTO comprobante) throws Exception {
        boolean retorno = false;
        EntityTransaction tx = this.em.getTransaction();
        tx.begin();
        try {
            ComprobantePago comp = this.em.find(ComprobantePago.class, Long.parseLong(String.valueOf(comprobante.getId_comprobante())));
            comp.setSerieComprobante(comprobante.getSerie_comprobante().trim());
            comp.setNumeroComprobante(comprobante.getNumero_comprobante().trim());
            this.em.merge(comp);
            this.em.flush();
            retorno = true;
            tx.commit();
        } catch (Exception e) {
            tx.rollback();
            throw e;
        }
        return retorno;
    }
}
